package com.atguigu.aspect;

import com.atguigu.annotations.MyRedisCache;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.expression.Expression;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

@Component
@Aspect
@Slf4j
public class MyRedisCacheAspect2 {

    @Autowired
    private RedisTemplate redisTemplate;
    @Around("@annotation(com.atguigu.annotations.MyRedisCache)")
    public Object add(ProceedingJoinPoint joinPoint){
        Object result = new Object();
        try {
            MethodSignature signature= (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            MyRedisCache annotation = method.getAnnotation(MyRedisCache.class);
            String keyPrefix = annotation.keyPrefix();
            String matchValue = annotation.matchValue();
            SpelExpressionParser parser = new SpelExpressionParser();
            Expression expression = parser.parseExpression(matchValue);
            StandardEvaluationContext context = new StandardEvaluationContext();
            Object[] args = joinPoint.getArgs();
            Parameter[] parameters = method.getParameters();
            for (int i = 0; i < parameters.length; i++) {
                System.out.println(parameters[i].getName()+args[i].toString());
                context.setVariable(parameters[i].getName(),args[i].toString());
            }
            String key = keyPrefix+":"+expression.getValue(context).toString();
            System.out.println("---key:"+key);
            result=redisTemplate.opsForValue().get(key);
            if (result!=null){
                System.out.println("-------redis有"+result);
                return result;
            }
            result=joinPoint.proceed();
            if (result!=null){
                System.out.println("------------redis里面没有,还要把结果存入redis,缓存补偿"+result);
                redisTemplate.opsForValue().set(key,result);
            }
        } catch (Throwable e) {
            throw new RuntimeException(e);
        }
        return result;
    }
}
